package cn.aixuxi.notebank.controller;

import cn.aixuxi.notebank.constant.DefConstant;
import cn.aixuxi.notebank.constant.StringConstant;
import cn.aixuxi.notebank.dto.*;
import cn.aixuxi.notebank.entity.*;
import cn.aixuxi.notebank.service.*;
import cn.aixuxi.notebank.util.ConverUtils;
import cn.aixuxi.notebank.util.JwtUtils;
import cn.aixuxi.notebank.util.PasswordUtils;
import cn.aixuxi.notebank.util.RedisUtils;
import cn.aixuxi.notebank.vo.CategoryVO;
import cn.hutool.extra.mail.MailUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.netflix.ribbon.proxy.annotation.Http;
//import lombok.experimental.Accessors;
//import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.annotation.RequiresPermissions;
//import org.omg.CosNaming.NamingContextPackage.NotEmpty;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 类描述 后台管理处理
 *
 * @author ruozhuliufeng
 * @version 1.0
 * @date 2020/12/1 23:53
 */
@Controller
@RequestMapping("/admin")
public class AdminController {


    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UserService userService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private TagService tagService;

    @Autowired
    private UpdateRecordService updateRecordService;

    @Autowired
    private NoteService noteService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IPermissionService permissionService;

    @Autowired
    private IRolePermissionService rolePermissionService;

    @Autowired
    private IUserRoleService userRoleService;


    @PostMapping("/login")
    public String login(HttpServletResponse response) {
        // 先判断Token是否有效，有效直接返回页面地址
        String token = response.getHeader(DefConstant.ACCESS_TOKEN);
        String verifyToken = String.valueOf(redisUtils.get(DefConstant.PREFIX_USER_TOKEN + token));
        if (!StringUtils.isEmpty(verifyToken)) {
            String username = JwtUtils.getUsername(verifyToken);
            UserEntity user = userService.findByUsername(username);
            if (user.getType() == 2) {
                return "admin/main";
            }
        }
        return "admin/index";
    }

    // ===========================分类管理相关====================================
    @GetMapping("/category")
    public String category(HttpSession session) {
        // 查询所有分类，并放到session中
        List<CategoryOutputDTO> list = categoryService.findList();
        session.setAttribute("categoryList", list);
        List<CategoryOutputDTO> categoryManagerList = list.stream().map(item -> {
            CategoryOutputDTO categoryOutputDTO = new CategoryOutputDTO();
            BeanUtils.copyProperties(item, categoryOutputDTO);
            Integer id = item.getParentId();
            if (id != null) {
                categoryOutputDTO.setCategoryParentName(categoryService.getById(item.getParentId()).getCategoryName());
            }
            return categoryOutputDTO;
        }).collect(Collectors.toList());
        session.setAttribute("categoryManagerList", categoryManagerList);
        // 分类总数
        Integer categoryCount = categoryService.count();
        session.setAttribute("categoryCount", categoryCount);
        return "admin/category";
    }

    /**
     * 功能描述: 分类添加（需要分类添加权限）
     *
     * @param categoryVO 添加的分类数据
     * @return : 重定向到分类页面
     * @author : ruozhuliufeng
     * @date : 2020/12/19 9:08
     */
    @RequiresPermissions({"category:add"})
    @PostMapping("/category/add")
    public String categoryAdd(CategoryVO categoryVO) {
        categoryService.save(categoryVO);
        return "redirect:/admin/category";
    }

    @GetMapping("/category/update")
    public String categoryUpdate(Integer id, HttpSession session) {
        // 根据ID获取数据
        CategoryEntity categoryEntity = categoryService.getById(id);
        CategoryOutputDTO categoryOutputDTO = new CategoryOutputDTO();
        BeanUtils.copyProperties(categoryEntity, categoryOutputDTO);
        if (categoryEntity.getParentId() != null) {
            // 获取父ID的分类名称
            categoryOutputDTO.setCategoryParentName(categoryService.getById(categoryEntity.getParentId()).getCategoryName());
        }
        session.setAttribute("category", categoryOutputDTO);
        return "admin/category_update";
    }

    /**
     * 功能描述: 分类编辑 （需要分类编辑权限）
     *
     * @param categoryVO  1
     * @param httpSession 2
     * @return : java.lang.String
     * @author : ruozhuliufeng
     * @date : 2020/12/19 9:02
     */
    @RequiresPermissions({"category:edit"})
    @PostMapping("/category/edit")
    public String categoryEdit(CategoryVO categoryVO, HttpSession httpSession) {
        categoryService.save(categoryVO);
        return "redirect:/admin/category";
    }

    /**
     * 功能描述: 根据分类ID删除分类
     *
     * @param id 分类ID
     * @return : 重定向到分类页面
     * @author : ruozhuliufeng
     * @date : 2020/12/19 9:04
     */
    @GetMapping("/category/delete")
    public String categoryDelete(Integer id) {
        // TODO 删除分类下的文章和子分类
        categoryService.removeById(id);
        return "redirect:/admin/category";
    }

    // ===========================分类管理相关结束====================================


    // ===========================笔记管理相关====================================

    /**
     * 功能描述: 跳转到笔记管理页面
     *
     * @param session 保存笔记列表
     * @return : 笔记管理页面路径
     * @author : ruozhuliufeng
     * @date : 2020/12/24 10:57
     */
    @GetMapping("/note")
    public String note(HttpSession session) {
        List<NoteOutputDTO> noteList = noteService.noteList();
        session.setAttribute("noteList", noteList);
        // 笔记总数
        Integer noteCount = noteService.count();
        session.setAttribute("noteCount", noteCount);
        return "admin/note";
    }

    /**
     * 功能描述:  跳转到笔记修改
     *
     * @param id      要修改的笔记
     * @param session 保存相关信息
     * @return : 笔记修改页面路径
     * @author : ruozhuliufeng
     * @date : 2020/12/24 11:03
     */
    @GetMapping("/note/update")
    public String noteUpdate(Integer id, HttpSession session) {
        return "admin/note_update";
    }

    /**
     * 功能描述: 根据ID删除笔记
     *
     * @param id 笔记删除
     * @return : 刷新页面
     * @author : ruozhuliufeng
     * @date : 2020/12/24 11:10
     */
    @GetMapping("/note/delete")
    public String noteDelete(Integer id) {
        noteService.removeById(id);
        return "redirect:/admin/note";
    }

    /**
     * 功能描述: 根据ID批量删除笔记
     *
     * @param ids 批量ID
     * @return : java.lang.String
     * @author : ruozhuliufeng
     * @date : 2020/12/24 11:11
     */
    @PostMapping("/note/deleteAll")
    public String noteDelete(String[] ids) {
        List<Integer> noteIds = ConverUtils.stringToList(ids);
        noteService.removeByIds(noteIds);
        return "redirect:/admin/note";
    }

    @GetMapping("note/noteAdd")
    public String noteAdd() {
        return "admin/note_add";
    }

    // ===========================笔记管理相关结束====================================

    // ===========================标签管理相关====================================

    /**
     * 功能描述:  标签页面跳转
     *
     * @param session 存储标签信息
     * @return : 标签页面路径
     * @author : ruozhuliufeng
     * @date : 2020/12/24 12:29
     */
    @GetMapping("/tag")
    public String tag(HttpSession session) {
        List<TagEntity> tagManagerList = tagService.list();
        session.setAttribute("tagManagerList", tagManagerList);
        // 标签总数
        Integer tagCount = tagService.count();
        session.setAttribute("tagCount", tagCount);
        return "admin/tag";
    }

    /**
     * 功能描述: 添加标签
     *
     * @param tagEntity 标签信息
     * @return : 刷新标签管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/24 12:35
     */
    @PostMapping("/tag/add")
    public String tagAdd(TagEntity tagEntity) {
        tagService.save(tagEntity);
        return "redirect:/admin/tag";
    }

    /**
     * 功能描述: 根据ID删除标签
     *
     * @param id 标签ID
     * @return : 刷新标签管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/24 12:37
     */
    @GetMapping("/tag/delete")
    public String tagDelete(Integer id) {
        tagService.removeById(id);
        return "redirect:/admin/tag";
    }

    /**
     * 功能描述: 根据ID修改标签
     *
     * @param id      标签ID
     * @param session 存储标签信息
     * @return : 修改标签路径
     * @author : ruozhuliufeng
     * @date : 2020/12/24 12:37
     */
    @GetMapping("/tag/update")
    public String tagUpdate(Integer id, HttpSession session) {
        TagEntity tagEntity = tagService.getById(id);
        session.setAttribute("updateTag", tagEntity);
        return "admin/tag_update";
    }

    /**
     * 功能描述: 修改标签
     *
     * @param updateTag 修改标签内容
     * @return : 刷新标签管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/24 12:41
     */
    @PostMapping("/tag/edit")
    public String tagEdit(TagEntity updateTag) {
        tagService.updateById(updateTag);
        return "redirect:/admin/tag";
    }

    // ===========================标签管理相关结束====================================

    // ============================角色管理相关=======================================

    /**
     * 功能描述: 跳转到角色管理页面
     *
     * @param session 存储角色信息
     * @return : 角色管理页面路径
     * @author : ruozhuliufeng
     * @date : 2020/12/24 12:56
     */
    @GetMapping("/role")
    public String role(HttpSession session) {
        List<RoleEntity> roleManagerList = roleService.list();
        session.setAttribute("roleManagerList", roleManagerList);
        // 所有权限ID列表
        List<PermissionEntity> permissionList = permissionService.list();
        session.setAttribute("permissionList", permissionList);
        // 所有角色
        Integer roleCount = roleService.count();
        session.setAttribute("roleCount", roleCount);
        return "admin/role";
    }


    /**
     * 功能描述: 跳转到角色修改页面
     *
     * @param id      角色ID
     * @param session 存储角色相关信息
     * @return : 修改角色页面地址
     * @author : ruozhuliufeng
     * @date : 2020/12/24 12:58
     */
    @GetMapping("/role/update")
    public String roleUpdate(Integer id, HttpSession session) {
        RoleEntity roleEntity = roleService.getById(id);
        session.setAttribute("updateRole", roleEntity);
        return "admin/role_update";
    }

    /**
     * 功能描述: 添加角色
     *
     * @param roleEntity 角色信息
     * @return : 刷新角色管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/24 13:24
     */
    @PostMapping("/role/add")
    public String roleAdd(RoleEntity roleEntity) {
        roleEntity.setAvailable(1);
        roleService.save(roleEntity);
        return "redirect:/admin/role";
    }

    /**
     * 功能描述: 删除角色
     *
     * @param id 角色ID
     * @return : 刷新角色管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/24 13:09
     */
    @GetMapping("/role/delete")
    public String roleDelete(Integer id) {
        roleService.removeById(id);
        return "redirect:/admin/role";
    }

    /**
     * 功能描述: 角色修改
     *
     * @param roleEntity 修改的角色信息
     * @return : 重定向到角色管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/24 13:11
     */
    @PostMapping("/role/edit")
    public String roleEdit(RoleEntity roleEntity) {
        roleService.updateById(roleEntity);
        return "redirect:/admin/role";
    }

    /**
     * 功能描述: 为角色添加权限
     *
     * @param roleId        角色ID
     * @param permissionIds 权限ID列表
     * @return : 刷新角色管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/24 14:18
     */
    @PostMapping("/role/addPermission")
    public String roleAddPermission(Integer roleId, String[] permissionIds) {

        List<Integer> permissions = ConverUtils.stringToList(permissionIds);
        System.out.println(permissions);
        permissions.stream().map(permissionId -> {
            RolePermissionEntity entity = new RolePermissionEntity(roleId, permissionId);
            if (!rolePermissionService.isExist(entity)) {
                return rolePermissionService.save(entity);
            }
            return null;
        }).collect(Collectors.toList());
        return "redirect:/admin/role";
    }

    // ===========================角色管理相关结束====================================


    // ============================权限管理相关======================================

    /**
     * 功能描述: 跳转到权限管理页面
     *
     * @param session 保存权限信息
     * @return : java.lang.String
     * @author : ruozhuliufeng
     * @date : 2020/12/28 15:03
     */
    @GetMapping("/permission")
    public String permission(HttpSession session) {
        List<PermissionEntity> permissionManagerList = permissionService.list();
        session.setAttribute("permissionManagerList", permissionManagerList);
        // 统计权限总数
        Integer permissionCount = permissionService.count();
        session.setAttribute("permissionCount", permissionCount);
        return "admin/permission";
    }

    /**
     * 功能描述: 添加权限信息
     *
     * @param permissionEntity 权限信息
     * @return : 刷新权限列表
     * @author : ruozhuliufeng
     * @date : 2020/12/28 15:03
     */
    @PostMapping("/permission/add")
    public String permissionAdd(PermissionEntity permissionEntity) {
        permissionService.save(permissionEntity);
        return "redirect:/admin/permission";
    }

    /**
     * 功能描述: 跳转到权限修改页面
     *
     * @return : java.lang.String
     * @author : ruozhuliufeng
     * @date : 2020/12/28 15:04
     */
    @GetMapping("/permission/update")
    public String permissionUpdate() {
        return "admin/permission_update";
    }

    /**
     * 功能描述: 修改权限
     *
     * @param permissionEntity 待修改的权限信息
     * @return : 刷新权限管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/28 15:05
     */
    @PostMapping("/permission/edit")
    public String permissionEdit(PermissionEntity permissionEntity) {
        permissionService.updateById(permissionEntity);
        return "redirect:/admin/permission";
    }

    /**
     * 功能描述: 根据ID删除权限
     *
     * @param id 权限ID
     * @return : 刷新权限管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/28 15:14
     */
    @GetMapping("/permission/delete")
    public String permissionDelete(Integer id) {
        permissionService.removeById(id);
        return "redirect:/admin/permission";
    }
    // ===========================权限管理相关结束====================================

    // ============================用户管理相关======================================

    /**
     * 功能描述: 跳转到用户管理页面
     *
     * @param session 保存相关数据
     * @return : 用户管理页面路径
     * @author : ruozhuliufeng
     * @date : 2020/12/24 16:12
     */
    @GetMapping("/user")
    public String user(HttpSession session) {
        List<UserEntity> list = userService.list();
        List<UserDTO> userManagerList = list.stream().map(item -> {
            UserDTO userDTO = new UserDTO();
            BeanUtils.copyProperties(item, userDTO);
            // 设置发表的文章总数
            QueryWrapper<NoteEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userDTO.getId());
            userDTO.setNoteCount(noteService.count(queryWrapper));
            // TODO 设置最后一次登录的时间
            userDTO.setLastLoginTime("2020-12-24 16:10:22");
            return userDTO;
        }).collect(Collectors.toList());
        session.setAttribute("userManagerList", userManagerList);
        // 获取所有角色列表
        List<RoleEntity> roleList = roleService.list();
        session.setAttribute("roleList", roleList);
        return "admin/user";
    }


    /**
     * 功能描述: 跳转到用户修改页面
     *
     * @param id      用户ID
     * @param session 保存用户相关信息
     * @return : java.lang.String
     * @author : ruozhuliufeng
     * @date : 2020/12/24 16:55
     */
    @GetMapping("/user/update")
    public String userUpdate(Integer id, HttpSession session) {
        UserEntity userEntity = userService.getById(id);
        session.setAttribute("updateUser", userEntity);
        return "admin/user_update";
    }

    @PostMapping("/user/userAdd")
    public String userAdd(UserEntity userEntity) {
        // 用户的盐值
        userEntity.setSalt(ConverUtils.randomGen(8));
        // 盐值加密
        userEntity.setPassword(PasswordUtils.encrypt(userEntity.getUsername(), userEntity.getPassword(), userEntity.getSalt()));
        // 默认级别为1
        userEntity.setType(DefConstant.USER);
        // 默认为未激活
        userEntity.setStatus(DefConstant.NO_ACTIVE);
        // 随机字符串
        String activeCode = UUID.randomUUID().toString();
        userEntity.setActiveCode(activeCode);
        userService.save(userEntity);
        // 将激活码放到Redis，并设置3天过期时间,设置邮箱为键
        redisUtils.set(userEntity.getEmail(), activeCode, DefConstant.ACTIVECODE_EXPIRE_TIME);
        // TODO 创建账号后由RabbitMQ接受消息并自动发送激活邮件
        MailUtil.send(userEntity.getEmail(), StringConstant.ACTIVE_TITLE, "<h1>账户激活</h1><a href='localhost:8006/user/active?activeCode=" + activeCode + "'>请点击该链接进行激活</a>", true);
        return "redirect:/admin/user";
    }

    /**
     * 功能描述: 根据ID删除用户
     *
     * @param id 用户ID
     * @return : 刷新用户管理界面
     * @author : ruozhuliufeng
     * @date : 2020/12/24 15:22
     */
    @GetMapping("/user/delete")
    public String userDelete(Integer id) {
        userService.removeById(id);
        return "redirect:/admin/user";
    }

    /**
     * 功能描述: 为用户添加角色信息
     *
     * @param uid     用户ID
     * @param roleIds 角色ID集合
     * @return : 刷新用户管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/24 16:28
     */
    @PostMapping("/user/addRole")
    public String addRole(Integer uid, String[] roleIds) {
        List<Integer> list = ConverUtils.stringToList(roleIds);
        list.stream().map(item -> {
            SysUserRoleEntity sysUserRoleEntity = new SysUserRoleEntity(uid, item);
            if (!userRoleService.isExist(sysUserRoleEntity)) {
                return userRoleService.save(sysUserRoleEntity);
            }
            return null;
        }).collect(Collectors.toList());
        return "redirect:/admin/user";
    }

    /**
     * 功能描述: 修改用户
     *
     * @param userEntity 待修改的用户信息
     * @return : 刷新用户管理页面
     * @author : ruozhuliufeng
     * @date : 2020/12/28 14:49
     */
    @PostMapping("/user/edit")
    public String editUser(UserEntity userEntity) {
        // 修改的密码需要重新加密
        userEntity.setPassword(PasswordUtils.encrypt(userEntity.getUsername(), userEntity.getPassword(), userEntity.getSalt()));
        userService.updateById(userEntity);
        return "redirect:/admin/user";
    }
    // ===========================用户管理相关结束====================================


    // ============================日志管理相关======================================

    @GetMapping("/operlog")
    public String operlog() {
        return "admin/operlog";
    }
    // ===========================日志管理相关结束====================================


    // ============================管理员管理相关======================================


    // ===========================管理员管理相关结束====================================

}
